/**
  ******************************************************************************
  * File Name          : ADS1262.c
  * Description        : This ADS1262 provides code for the configuration
  *                      of the ADS1262 instances.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under UlADS1262ate Liberty license
  * SLA0044, the "License"; You may not use this ADS1262 except in compliance with
  * the License. You may obtain a copy of the License at:
  *                             www.st.com/SLA0044
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "ADS1262.h"

/* USER CODE BEGIN 0 */
#include "lcd.h"
/* USER CODE END 0 */

/* USER CODE BEGIN 1 */


//get chip ID, 0:1262; 1:1263
uint8_t ADS1262_Get_ID(void)
{
  uint8_t pRxData[3] ;
  uint8_t pTxData[3] ={ CMD_READ|ADS1262_ID,0,0 } ;

  SPI1_CS_ADS_0;
  HAL_SPI_TransmitReceive( &hspi1 ,  pTxData,  pRxData, 3 , 20);
  SPI1_CS_ADS_1;

  return pRxData[2];
}


//ADS1262 init,
//Set channel
uint8_t ADS1262_Init(void)
{

  uint8_t pTxData[3] ={
		  CMD_WRITE|ADS1262_MODE2,
		  0,
		  ADS_PGA_GAIN_SPS_MODE
  };

  //1. open 5V 3.3V power of ADC chip
  ADS_POWER_CTL_1;

  //2. pull up the reset pin, wait for stable
  ADS_RESET_0;
  HAL_Delay(100);
  ADS_RESET_1;
  HAL_Delay(100);

  //3. check chip's ID, if not ADS1262, stop
  if( 0xE0 & ADS1262_Get_ID() )
	  return 1;

  //4. set register for configure chip mode
  SPI1_CS_ADS_0;
  HAL_SPI_Transmit( &hspi1 ,  pTxData,  3 , 20);
  SPI1_CS_ADS_1;

  //5. start adc translation
  ADS_START_1;

  //6. start adc Calibration
  ADS1262_Calibration_ADC();

  //7. set CH444G EN, low is active;
  ADC_SWITCH_EN_0;

#if Debug_Version
  /*----Used for Debug Mode ,set test DAC-----*/
  ADS1262_Set_Test_DAC();
  /*----Used for Debug Mode ,set sample channel which is connnet to test DAC-----*/
  ADS1262_Set_Channel(0x45);
  //set CH444G DISABLE, low is active;
  ADC_SWITCH_EN_1;

  /*----Used for temp Mode -----*/
//  ADS1262_Set_Channel(0xBB);
#endif


  return 0;
}


//write data to ads1262,set different channel
//Num : 0x01 0x23 0x45 0xBB(inter temp)
void ADS1262_Set_Channel( uint8_t num )
{

	uint8_t pTxData[3] ={ CMD_WRITE|ADS1262_INPMUX, 0, 0 } ;

	switch (num) {
		case 0x01:
			pTxData[2] = ADS1262_INPUT_01;
			break;
		case 0x23:
			pTxData[2] = ADS1262_INPUT_23;
			break;
		case 0x45:
			pTxData[2] = ADS1262_INPUT_45;
			break;
		case 0xBB:
			pTxData[2] = ADS1262_INPUT_BB;
			break;
		default:
			break;
	}

	SPI1_CS_ADS_0;
	HAL_SPI_Transmit( &hspi1 ,  pTxData,  3 , 2);
	SPI1_CS_ADS_1;
}

//control CH44G GPIO ,set different channel
//control all of three CH444
//Num : 1、2、3、4
void CH444G_Set_Channel( uint8_t num )
{
	switch (num) {
		case 1:
			ADC_SWITCH_IN0_0;
			ADC_SWITCH_IN1_0;
			break;
		case 2:
			ADC_SWITCH_IN0_1;
			ADC_SWITCH_IN1_0;
			break;
		case 3:
			ADC_SWITCH_IN0_0;
			ADC_SWITCH_IN1_1;
			break;
		case 4:
			ADC_SWITCH_IN0_1;
			ADC_SWITCH_IN1_1;
			break;
		default:
			ADC_SWITCH_IN0_0;
			ADC_SWITCH_IN1_0;
			break;
	}

}


uint32_t ADS1262_Get_ADC(void)
{
  uint8_t pRxData[7] ;
  uint8_t pTxData[7] ={ ADS1262_ADC1_DATA, 0, 0, 0, 0, 0, 0 } ;
  uint32_t reasult=0;
//  float val=0;

  //start adc translation
  ADS_START_1;

  //wait adc translation finish
  while(ADS_DRDY);

  //read register for data
  SPI1_CS_ADS_0;
  HAL_SPI_TransmitReceive( &hspi1 ,  pTxData,  pRxData, 7 , 2);
  SPI1_CS_ADS_1;

  //stop adc translation
  ADS_START_0;

#if Debug_Version
//  val = (((uint32_t)pRxData[2]<<24)|((uint32_t)pRxData[3]<<16)|((uint32_t)pRxData[4]<<8)|(uint32_t)pRxData[5])*2.5/0x7FFFFFFF;
//  LCD_ShowNum(10,100,(((uint32_t)pRxData[2]<<24)|((uint32_t)pRxData[3]<<16)|((uint32_t)pRxData[4]<<8)|(uint32_t)pRxData[5]),10,12,0,BLACK,WHITE);
#endif

  reasult = (((uint32_t)pRxData[2]<<24)|((uint32_t)pRxData[3]<<16)|((uint32_t)pRxData[4]<<8)|(uint32_t)pRxData[5]) ;
  return reasult;
}






//USE_ANALOG_SWITCH
/*
uint8_t CH_x :支持8通道，从1到12
uint32_t 返回值：返回实际使能的通道值
*/
uint32_t ADS1262_GET_ADC_DATA(uint8_t CH_x)
{

  uint32_t result=0;

  switch( CH_x )
  {

    case 1 :
    	CH444G_Set_Channel( 1 );
    	ADS1262_Set_Channel( 0x01 );
    	result = ADS1262_Get_ADC();
    break;

    case 2 :
    	CH444G_Set_Channel( 2 );
    	ADS1262_Set_Channel( 0x01 );
    	result = ADS1262_Get_ADC();
    break;

    case 3 :
    	CH444G_Set_Channel( 3 );
    	ADS1262_Set_Channel( 0x01 );
    	result = ADS1262_Get_ADC();
    break;

    case 4 :
    	CH444G_Set_Channel( 4 );
    	ADS1262_Set_Channel( 0x01 );
    	result = ADS1262_Get_ADC();
    break;

    case 5 :
    	CH444G_Set_Channel( 1 );
    	ADS1262_Set_Channel( 0x23 );
    	result = ADS1262_Get_ADC();
    break;

    case 6 :
    	CH444G_Set_Channel( 2 );
    	ADS1262_Set_Channel( 0x23 );
    	result = ADS1262_Get_ADC();
    break;

    case 7 :
    	CH444G_Set_Channel( 3 );
    	ADS1262_Set_Channel( 0x23 );
    	result = ADS1262_Get_ADC();
    break;

    case 8 :
    	CH444G_Set_Channel( 4 );
    	ADS1262_Set_Channel( 0x23 );
    	result = ADS1262_Get_ADC();
    break;

    case 9 :
    	CH444G_Set_Channel( 1 );
    	ADS1262_Set_Channel( 0x45 );
    	result = ADS1262_Get_ADC();
    break;

    case 10 :
    	CH444G_Set_Channel( 2 );
    	ADS1262_Set_Channel( 0x45 );
    	result = ADS1262_Get_ADC();
    break;

    case 11 :
    	CH444G_Set_Channel( 3 );
    	ADS1262_Set_Channel( 0x45 );
    	result = ADS1262_Get_ADC();
    break;

    case 12 :
    	CH444G_Set_Channel( 4 );
    	ADS1262_Set_Channel( 0x45 );
    	result = ADS1262_Get_ADC();
    break;

    default:
    	CH444G_Set_Channel( 1 );
    	ADS1262_Set_Channel( 0x01 );
    	result = ADS1262_Get_ADC();
      break;
  }
  return result;
}


//USE_ANALOG_SWITCH
/*
uint32_t ADC_CHx_Result[12]:保存12个通道的数组，
*/
void ADS1262_GET_ADC_DATA_FAST( uint32_t ADC_CHx_Result[12] )
{

  ADS1262_Set_Channel( 0x01 );

  CH444G_Set_Channel( 1 );
  ADC_CHx_Result[0] = ADS1262_Get_ADC();
  CH444G_Set_Channel( 2 );
  ADC_CHx_Result[1] = ADS1262_Get_ADC();
  CH444G_Set_Channel( 3 );
  ADC_CHx_Result[2] = ADS1262_Get_ADC();
  CH444G_Set_Channel( 4 );
  ADC_CHx_Result[3] = ADS1262_Get_ADC();

  ADS1262_Set_Channel( 0x23 );

  CH444G_Set_Channel( 1 );
  ADC_CHx_Result[4] = ADS1262_Get_ADC();
  CH444G_Set_Channel( 2 );
  ADC_CHx_Result[5] = ADS1262_Get_ADC();
  CH444G_Set_Channel( 3 );
  ADC_CHx_Result[6] = ADS1262_Get_ADC();
  CH444G_Set_Channel( 4 );
  ADC_CHx_Result[7] = ADS1262_Get_ADC();

  ADS1262_Set_Channel( 0x45 );

  CH444G_Set_Channel( 1 );
  ADC_CHx_Result[8] = ADS1262_Get_ADC();
  CH444G_Set_Channel( 2 );
  ADC_CHx_Result[9] = ADS1262_Get_ADC();
  CH444G_Set_Channel( 3 );
  ADC_CHx_Result[10] = ADS1262_Get_ADC();
  CH444G_Set_Channel( 4 );
  ADC_CHx_Result[11] = ADS1262_Get_ADC();

}



float ADS1262_Temperature_sensor_DATA_GET(void)
{
	uint32_t result=0;
	float temp=0;
	uint8_t pTxData[3] ={	CMD_WRITE|ADS1262_MODE2,  0,  0x04 }; //ADS1262_MODE2:used PGA ,Gain=1; 20SPS;for temp

	SPI1_CS_ADS_0;
	HAL_SPI_Transmit( &hspi1 ,  pTxData,  3 , 2);
	SPI1_CS_ADS_1;

	ADS1262_Set_Channel(0xBB);

	result = ADS1262_Get_ADC();

	//ADS1262_MODE2
	pTxData[0] =	CMD_WRITE|ADS1262_MODE2;
	pTxData[1] =	0 ;
	pTxData[2] =	ADS_PGA_GAIN_SPS_MODE ;

	SPI1_CS_ADS_0;
	HAL_SPI_Transmit( &hspi1 ,  pTxData,  3 , 2);
	SPI1_CS_ADS_1;

	temp = (result*0.0011641532-122400)/420 +25;

	//根据水银温度计的数据来对温度进行标定
	temp = temp - 6.4 ;

	return temp;
}


//转换电压，以mV显示
float ADC1262_Change_ADC_to_VOL(uint32_t ADC_DATA)
{
	float result=0.0;
  //负数变成正数
  if( ADC_DATA >= 0x80000000 ){
    ADC_DATA = 0xFFFFFFFF-ADC_DATA ;
    result = -1.0*ADC_DATA*ADS1262_VREF/FULL_RANGE/PGA_GAIN*1000;//mV
  } else {
	result = ADC_DATA*ADS1262_VREF/FULL_RANGE/PGA_GAIN*1000;//mV
  }

  return result;
}




/*
float Voltage:输入电压值，根据电压值转换成温度值，冷端补偿为ADS1262内部温度传感器
*/
float ADS1262_Change_VOL_to_TEMP( float temp_of_cold_point , float Voltage )
{
	float temp_of_hot_point = 0;

	//计算热端温度
	temp_of_hot_point = temp_of_cold_point \
			+ 0.000001*Voltage*Voltage*Voltage*Voltage*Voltage*Voltage\
			+0.0001*Voltage*Voltage*Voltage*Voltage*Voltage\
			-0.0059*Voltage*Voltage*Voltage*Voltage\
			+0.0888*Voltage*Voltage*Voltage\
			+0.483*Voltage*Voltage\
			+25.268*Voltage\
			+0.0801;

////23-05-22-数据校准 添加，在06.10次校准中同步体现,因此注释掉
//	temp_of_hot_point = temp_of_hot_point * 0.94787 + 1.3033;

//	23-06-10校准
//	temp_of_hot_point = \
//			  0.00003 * temp_of_hot_point * temp_of_hot_point * temp_of_hot_point \
//			- 0.0021  * temp_of_hot_point * temp_of_hot_point \
//			+ 1.0552  * temp_of_hot_point \
//			- 0.1861 ;

//	23-06-18校准
	temp_of_hot_point = \
			- 0.0014  * temp_of_hot_point * temp_of_hot_point \
			+ 1.0807  * temp_of_hot_point \
			+ 0.8554 ;

	return temp_of_hot_point;
}


/*
float Temp_Result[12]:保存12个通道的温度数值，
*/
void ADS1262_GET_Thermocouple_temp( float Temp_Result[12] )
{
	uint8_t i=0;
	uint32_t ADC_CHx_Result[12];
	float temp_of_cold_point=0;

	//获取各个通道的ADC采集数据
	ADS1262_GET_ADC_DATA_FAST( ADC_CHx_Result );

	//Get ADS1262 Temp
	temp_of_cold_point = ADS1262_Temperature_sensor_DATA_GET();

	//根据数据拟合的公式来计算温度值,对于没有连接热电偶的通道，统一显示数字0.0
	for (i = 0; i < 12; i++) {
		Temp_Result[i] = ADS1262_Change_VOL_to_TEMP( temp_of_cold_point , ADC1262_Change_ADC_to_VOL(ADC_CHx_Result[i]) );
		if( Temp_Result[i] >= 300000 || Temp_Result[i] <= -300000 )
			Temp_Result[i] = 0.0;
		else if( Temp_Result[i] >= MAX_TEMP_CAN_Record )
			Temp_Result[i] = MAX_TEMP_CAN_Record;
	}
}



/*----Used for Debug Mode ,set test DAC-----*/
//write data to ads1262,set diff channel,0.0078V
void ADS1262_Set_Test_DAC(void)
{

  uint8_t pTxData[4] ={ CMD_WRITE|ADS1262_TDACP, 1, 0x80 , 0x83 } ;

  SPI1_CS_ADS_0;
  HAL_SPI_Transmit( &hspi1 ,  pTxData,  4 , 20);
  SPI1_CS_ADS_1;

}


/*----Used for Calibration Mode ,Calibration ADC1-----*/
void ADS1262_Calibration_ADC(void)
{
	uint8_t pTxData[3] ={ CMD_WRITE|ADS1262_INPMUX, 0, 0 } ;

	uint8_t pRxData_Calibra[5] ={ 0 } ;
	uint8_t pTxData_Calibra[5] ={ CMD_READ|ADS1262_OFCAL0, 2, 0, 0, 0} ;

	//1. Enable continuous-conversion mode (ADC1 only).
	/* ADS1262 default setting is continuous-conversion mode */

	//2. Select the desired gain and reference voltage of the ADC.
	/* ADS1262_MODE2:used PGA ,Gain=32; 20SPS; */

	/*--------------------------offset self-calibration-------------------------------*/

	//3. Choose calibration type: offset self-calibration
	//program the ADC1 or ADC2 input multiplexer register to FFh to open all inputs
	pTxData[2] = ADS1262_INPUT_FLOAT;
	SPI1_CS_ADS_0;
	HAL_SPI_Transmit( &hspi1 ,  pTxData,  3 , 20);
	SPI1_CS_ADS_1;

	//4. Start conversions:
	//start adc translation
	ADS_START_1;
	HAL_Delay(1);

	//5. Send the desired calibration command.
	pTxData[0] = CMD_SFOCAL1;
	SPI1_CS_ADS_0;
	HAL_SPI_Transmit( &hspi1 ,  pTxData,  1 , 10);

	//wait adc calibration finish
	while(ADS_DRDY);
	SPI1_CS_ADS_1;
	HAL_Delay(1);

	//Get the new offset calibration values
	SPI1_CS_ADS_0;
	HAL_SPI_TransmitReceive( &hspi1 ,  pTxData_Calibra,  pRxData_Calibra, 5 , 50);
	SPI1_CS_ADS_1;

	/*--------------------------system calibration-------------------------------*/

//	//3. Choose calibration type: system calibration
//	//select the input channel and short the external inputs (offset calibration)
//	CH444G_Set_Channel( 1 );
//	pTxData[2] = ADS1262_INPUT_01;
//	SPI1_CS_ADS_0;
//	HAL_SPI_Transmit( &hspi1 ,  pTxData,  3 , 20);
//	SPI1_CS_ADS_1;
//
//	//4. Start conversions:
//	//start adc translation
//	ADS_START_1;
//	HAL_Delay(1);
//
//	//5. Send the desired calibration command.
//	pTxData[0] = CMD_SYOCAL1;
//	SPI1_CS_ADS_0;
//	HAL_SPI_Transmit( &hspi1 ,  pTxData,  1 , 10);
//
//	//wait adc calibration finish
//	while(ADS_DRDY);
//	SPI1_CS_ADS_1;
//	HAL_Delay(1);
//
//	//Get the new offset calibration values
//	SPI1_CS_ADS_0;
//	HAL_SPI_TransmitReceive( &hspi1 ,  pTxData_Calibra,  pRxData_Calibra, 5 , 50);
//	SPI1_CS_ADS_1;

}




/* USER CODE END 1 */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
